package com.crrc.sandameter

import android.annotation.SuppressLint
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.provider.Settings
import android.util.Log
import android_serialport_api.ComPort
import androidx.lifecycle.MutableLiveData
import com.crrc.sandameter.device.COMUtil
import com.crrc.sandameter.device.REGISTER_ADD
import java.util.Locale

object DeviceManager {

    const val TAG = "DeviceManager"
    const val COM_NAME = "/dev/ttyS4"
    val deviceData = MutableLiveData<String>()
    private var registerAdd = ""
    private val dataHandler = ComPort.DataHandler { _, buffer, size ->
        val msg = Message.obtain()
        msg.what = 100
        msg.obj = buffer
        msg.arg1 = size
        mHandler.sendMessage(msg)
    }

    /**
     * 获取应用版本名字
     */
    fun getVersionName(): String {
        return AppContext.getContext().packageManager.getPackageInfo(AppContext.getContext().packageName,
            0).versionName ?: ""
    }

    private var mHandler = @SuppressLint("HandlerLeak") object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            if (msg.what == 100) {
                val data = msg.obj as ByteArray
                val len = msg.arg1
                val comdata: String = bytes2HexString(data, len)
                Log.d(TAG, "收到数据：$comdata")
                deviceData.postValue("$registerAdd$comdata")
            }
        }
    }

    /**
     * 获取设备唯一标识
     */
    @SuppressLint("HardwareIds")
    fun getAndroidID(): String {
        return Settings.Secure.getString(AppContext.getContext().contentResolver,
            Settings.Secure.ANDROID_ID)
    }

    /**
     * 连接锁控板串口
     */
    fun deviceInit(comName: String,
        boardRate: Int = 19200,
        initDeviceCallback: InitDeviceCallback) {
        val isSuccess = ComPort.getInstance().open(comName, boardRate, dataHandler)
        if (isSuccess) {
            initDeviceCallback.initSuccess()
            Log.d(TAG, "打开串口成功")
        } else {
            initDeviceCallback.initFailed()
            Log.d(TAG, "打开串口失败")
        }
    }

    fun bytes2HexString(b: ByteArray, len: Int): String {
        var ret = ""
        for (i in 0 until len) {
            var hex = Integer.toHexString(b[i].toInt() and 0xFF)
            if (hex.length == 1) {
                hex = "0$hex"
            }
            ret += hex.uppercase(Locale.getDefault())
        }
        return ret
    }

    /**
     * 获取设备版本号
     */
    fun getDeviceVersion() {
        registerAdd = REGISTER_ADD.DEVICE_VERSION
        val comString =
            "${COMUtil.DEVICE_ADDRESS}${COMUtil.READ_COM}${REGISTER_ADD.DEVICE_VERSION}0001"
        val com = COMUtil.getFullModbusCommandHexString(comString)
        Log.d(TAG, "发送获取设备版本号指令：$com")
        ComPort.getInstance().sendData(com)
    }

    /**
     * 执行清零操作
     * @param model 清零方式，0：清零，1：清零且设置默认零位
     */
    fun zeroDevice(model: Int) {
        registerAdd = REGISTER_ADD.ZERO_VALUE
        val data = if (model == 0) "0000" else "0001"
        val comString =
            "${COMUtil.DEVICE_ADDRESS}${COMUtil.WRITE_COM}${REGISTER_ADD.ZERO_VALUE}$data"
        val com = COMUtil.getFullModbusCommandHexString(comString)
        Log.d(TAG, "发送清零指令：$com")
        ComPort.getInstance().sendData(com)
    }

    /**
     * 标定设备
     * @param weight 重量（单位：kg）
     * @param point 点位
     */
    fun calibrateDevice(weight: Int, point: Int) {
        registerAdd = when (point) {
            1 -> REGISTER_ADD.POINT1_VALUE
            2 -> REGISTER_ADD.POINT2_VALUE
            3 -> REGISTER_ADD.POINT3_VALUE
            else -> REGISTER_ADD.POINT1_VALUE
        }
        val data = String.format("%04X", weight) //转化为4位16进制字符串
        val comString = "${COMUtil.DEVICE_ADDRESS}${COMUtil.WRITE_COM}${registerAdd}$data"
        val com = COMUtil.getFullModbusCommandHexString(comString)
        Log.d(TAG, "发送标定指令：$com")
        ComPort.getInstance().sendData(com)
    }

    /**
     * 获取重量
     */
    fun getWeight() {
        registerAdd = REGISTER_ADD.WEIGHT_VALUE
        val comString =
            "${COMUtil.DEVICE_ADDRESS}${COMUtil.READ_COM}${REGISTER_ADD.WEIGHT_VALUE}0002"
        val com = COMUtil.getFullModbusCommandHexString(comString)
        Log.d(TAG, "发送获取重量指令：$com")
        ComPort.getInstance().sendData(com)
    }

    /**
     * 设置量程
     */
    fun setRange(range: Int) {
        registerAdd = REGISTER_ADD.RANGE_VALUE
        val data = String.format("%04X", range) //转化为4位16进制字符串
        val comString = "${COMUtil.DEVICE_ADDRESS}${COMUtil.WRITE_COM}${registerAdd}$data"
        val com = COMUtil.getFullModbusCommandHexString(comString)
        Log.d(TAG, "发送设置量程指令：$com")
        ComPort.getInstance().sendData(com)
    }

    /**
     * 设置分度值
     */
    fun setScale(scale: Int) {
        registerAdd = REGISTER_ADD.SCALE_VALUE
        val data = String.format("%04X", scale) //转化为4位16进制字符串
        val comString = "${COMUtil.DEVICE_ADDRESS}${COMUtil.WRITE_COM}${registerAdd}$data"
        val com = COMUtil.getFullModbusCommandHexString(comString)
        Log.d(TAG, "发送设置分度值指令：$com")
        ComPort.getInstance().sendData(com)
    }

    /**
     * 开启/关闭判稳锁定
     * @param lock 锁定状态，true：开启锁定，false：关闭锁定
     */
    fun setLock(lock: Boolean) {
        registerAdd = REGISTER_ADD.LOCK_VALUE
        val data = if (lock) "0001" else "0000"
        val comString = "${COMUtil.DEVICE_ADDRESS}${COMUtil.WRITE_COM}${registerAdd}$data"
        val com = COMUtil.getFullModbusCommandHexString(comString)
        Log.d(TAG, "发送判稳锁定指令：$com")
        ComPort.getInstance().sendData(com)
    }

    /**
     * 开启/关闭蠕变跟踪
     * @param track 跟踪状态，true：开启跟踪，false：关闭跟踪
     */
    fun setTrack(track: Boolean) {
        registerAdd = REGISTER_ADD.TRACK_VALUE
        val data = if (track) "0001" else "0000"
        val comString = "${COMUtil.DEVICE_ADDRESS}${COMUtil.WRITE_COM}${registerAdd}$data"
        val com = COMUtil.getFullModbusCommandHexString(comString)
        Log.d(TAG, "发送蠕变跟踪指令：$com")
        ComPort.getInstance().sendData(com)
    }
}